package com.komorebi.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.komorebi.common.Const;
import com.komorebi.common.Result;
import com.komorebi.entity.SysRole;
import com.komorebi.entity.SysRoleMenu;
import com.komorebi.entity.SysUserRole;
import com.komorebi.mapper.SysRoleMapper;
import com.komorebi.service.impl.SysUserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author komorebi
 * @since 2021-11-19
 */
@RestController
@RequestMapping("/sys/role")
public class SysRoleController extends BaseController {


    //根据角色id返回角色信息，并且包含对应的menuId
    @GetMapping("/info/{id}")
    public Result info(@PathVariable(name = "id") Long id){
        SysRole sysRole = sysRoleService.getById(id);
        //获取角色相关联的菜单id
        List<SysRoleMenu> roleMenus = sysRoleMenuService.list(new QueryWrapper<SysRoleMenu>().eq("role_id",id));
        List<Long> menuIds = roleMenus.stream().map(p -> p.getMenuId()).collect(Collectors.toList());

        sysRole.setMenuIds(menuIds);
        return Result.success(sysRole);
    }
    //search
    @GetMapping("/list")
    @PreAuthorize("hasAuthority('sys:role:list')")
    public Result list(String name,Long current,Long size){
        Page<SysRole> page = new Page<>(current,size);
        Page<SysRole> rolePage = sysRoleService.page(page, StringUtils.isBlank(name) ? null : new QueryWrapper<SysRole>().eq("name", name));
        return Result.success(rolePage);
    }

    //新增
    @PostMapping("/save")
    @PreAuthorize("hasAuthority('sys:role:save')")
    public Result save(@Validated @RequestBody SysRole sysRole){
        //添加时设置create时间
        sysRole.setCreated(LocalDateTime.now());
        sysRole.setStatu(Const.STATUS_ON);
        sysRoleService.save(sysRole);
        return Result.success(sysRole);
    }
    //修改
    @PostMapping("/update")
    @PreAuthorize("hasAuthority('sys:role:update')")
    public Result update(@Validated @RequestBody SysRole sysRole){
        //修改时设置update时间
        sysRole.setUpdated(LocalDateTime.now());
        sysRoleService.updateById(sysRole);

        //角色信息改变时，删除角色对应权限的缓存
        sysUserService.clearUserAuthorityInfoByRoleId(sysRole.getId());
        return Result.success(sysRole);
    }
    //单项删除和批量删除
    @PostMapping("/delete")
    @PreAuthorize("hasAuthority('sys:role:delete')")
    @Transactional//添加事务，保证执行or回退
    public Result delete(@RequestBody Long [] ids){
        sysRoleService.removeByIds(Arrays.asList(ids));

        //角色信息改变时，删除角色对应权限的缓存
        Arrays.stream(ids).forEach(id -> {
            // 更新缓存
            sysUserService.clearUserAuthorityInfoByRoleId(id);
        });
        //删除role_user、role_menu相关项
        //QueryWrapper<SysUserRole>().in("role_id",ids)使用的时in不是eq
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().in("role_id",ids));
        sysRoleMenuService.remove(new QueryWrapper<SysRoleMenu>().in("role_id",ids));
        return Result.success("删除成功");
    }
    //分配权限
    @PostMapping("/perm/{roleId}")
    @PreAuthorize("hasAuthority('sys:role:perm')")
    @Transactional
    public Result getRoleList(@PathVariable(name = "roleId") Long roleId,@RequestBody Long [] menuIds){
        List<SysRoleMenu> roleMenuList = new ArrayList<>();

        Arrays.stream(menuIds).forEach(menuId -> {
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setRoleId(roleId);
            sysRoleMenu.setMenuId(menuId);
            roleMenuList.add(sysRoleMenu);
        });
        //先删除之前的记录(因为我们在分配权限时，之前的权限可能也改变了)
        sysRoleMenuService.remove(new QueryWrapper<SysRoleMenu>().eq("role_id",roleId));
        //再存入新的记录
        sysRoleMenuService.saveBatch(roleMenuList);
        //删除缓存
        sysUserService.clearUserAuthorityInfoByRoleId(roleId);
        return Result.success("分配权限操作成功");
    }


}
